﻿namespace GamePlus.OpenAuth.V20
{
  //  using Codeplex.Data;
 //   using Microsoft.CSharp.RuntimeBinder;
    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Diagnostics;
    using System.IO;
    using System.Net;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Web;
    public class OAuth
    {
        // Fields
        private const string ACCESS_TOKEN_URL = "https://api.weibo.com/oauth2/access_token";
        private const string AUTHORIZE_URL = "https://api.weibo.com/oauth2/authorize";

        // Methods
        public OAuth(string clientID, string clientSecret, string accessToken ="", string refreshToken ="")
        {
            this.ClientID = clientID;
            this.ClientSecret = clientSecret;
            this.AccessToken = accessToken ?? string.Empty;
            this.RefreshToken = refreshToken ?? string.Empty;
        }

        public bool ClientLogin(string passport, string password, string callbackUrl)
        {
            bool flag = false;
            HttpWebRequest request = WebRequest.Create("https://api.weibo.com/oauth2/authorize") as HttpWebRequest;
            request.Referer = this.GetAuthorizeURL(callbackUrl, ResponseType.Code, null, DisplayType.Default);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            string s = string.Format("action=submit&withOfficalFlag=0&ticket=&isLoginSina=&response_type=code&regCallback=&redirect_uri={0}&client_id={1}&state=&from=&userId={2}&passwd={3}", new object[] { HttpUtility.UrlEncode(callbackUrl), HttpUtility.UrlEncode(this.ClientID), HttpUtility.UrlEncode(passport), HttpUtility.UrlEncode(password) });
            byte[] bytes = Encoding.Default.GetBytes(s);
            request.ContentLength = bytes.Length;
            using (Stream stream = request.GetRequestStream())
            {
                try
                {
                    stream.Write(bytes, 0, bytes.Length);
                }
                catch (Exception exception)
                {
                    throw exception;
                }
                finally
                {
                    stream.Close();
                }
            }
            using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
            {
                if ((response == null) || (response.ResponseUri == null))
                {
                    return flag;
                }
                NameValueCollection values = HttpUtility.ParseQueryString(response.ResponseUri.Query);
                if (string.IsNullOrEmpty(values["code"]))
                {
                    return flag;
                }
                string code = values["code"];
                try
                {
                    if (!string.IsNullOrEmpty(this.GetAccessTokenByAuthorizationCode(code, callbackUrl)))
                    {
                        flag = true;
                    }
                }
                catch
                {
                }
            }
            return flag;
        }

        internal string GetAccessToken(GrantType type, Dictionary<string, string> parameters)
        {
            List<WeiboStringParameter> list = new List<WeiboStringParameter> {
            new WeiboStringParameter { Name = "client_id", Value = this.ClientID },
            new WeiboStringParameter { Name = "client_secret", Value = this.ClientSecret }
        };
            switch (type)
            {
                case GrantType.AuthorizationCode:
                    list.Add(new WeiboStringParameter { Name = "grant_type", Value = "authorization_code" });
                    list.Add(new WeiboStringParameter { Name = "code", Value = parameters["code"] });
                    list.Add(new WeiboStringParameter { Name = "redirect_uri", Value = parameters["redirect_uri"] });
                    break;

                case GrantType.Password:
                    list.Add(new WeiboStringParameter { Name = "grant_type", Value = "password" });
                    list.Add(new WeiboStringParameter { Name = "username", Value = parameters["username"] });
                    list.Add(new WeiboStringParameter { Name = "password", Value = parameters["password"] });
                    break;

                case GrantType.RefreshToken:
                    list.Add(new WeiboStringParameter { Name = "grant_type", Value = "refresh_token" });
                    list.Add(new WeiboStringParameter { Name = "refresh_token", Value = parameters["refresh_token"] });
                    break;
            }
            string str = this.Request("https://api.weibo.com/oauth2/access_token", RequestMethod.Post, false, list.ToArray());
            if (!string.IsNullOrEmpty(str))
            {
                dynamic obj2 =  DynamicJson.Parse(str);
                this.AccessToken = (string)obj2.access_token;
                return (string)obj2.access_token;
            }
            return string.Empty;
        }

        public string GetAccessTokenByAuthorizationCode(string code, string callbackUrl)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("code", code);
            parameters.Add("redirect_uri", callbackUrl);
            return this.GetAccessToken(GrantType.AuthorizationCode, parameters);
        }

        public string GetAccessTokenByPassword(string passport, string password)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("username", passport);
            parameters.Add("password", password);
            return this.GetAccessToken(GrantType.Password, parameters);
        }

        public string GetAccessTokenByRefreshToken(string refreshToken)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("refresh_token", refreshToken);
            return this.GetAccessToken(GrantType.RefreshToken, parameters);
        }

        public string GetAuthorizeURL(string callbackUrl, ResponseType response = 0, string state ="", DisplayType display = 0)
        {
            Dictionary<string, string> dictionary2 = new Dictionary<string, string>();
            dictionary2.Add("client_id", this.ClientID);
            dictionary2.Add("redirect_uri", callbackUrl);
            dictionary2.Add("response_type", response.ToString().ToLower());
            dictionary2.Add("state", state ?? string.Empty);
            dictionary2.Add("display", display.ToString().ToLower());
            Dictionary<string, string> parameters = dictionary2;
            return new UriBuilder("https://api.weibo.com/oauth2/authorize") { Query = Utility.BuildQueryString(parameters) }.ToString();
        }

        internal string Request(string url, RequestMethod method = 0, bool multi = false, params WeiboParameter[] parameters)
    {
        StreamReader reader;
        UriBuilder builder = new UriBuilder(url);
        string str2 = string.Empty;
        switch (method)
        {
            case RequestMethod.Get:
                builder.Query = Utility.BuildQueryString(parameters);
                break;

            case RequestMethod.Post:
                if (!multi)
                {
                    builder.Query = Utility.BuildQueryString(parameters);
                }
                break;
        }
        HttpWebRequest request = WebRequest.Create(builder.Uri) as HttpWebRequest;
        request.ServicePoint.Expect100Continue = false;
        request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)";
        if (!string.IsNullOrWhiteSpace(this.AccessToken))
        {
            request.Headers["Authorization"] = string.Format("OAuth2 {0}", this.AccessToken);
        }
        switch (method)
        {
            case RequestMethod.Get:
                request.Method = "GET";
                break;

            case RequestMethod.Post:
            {
                request.Method = "POST";
                if (!multi)
                {
                    request.ContentType = "application/x-www-form-urlencoded";
                    using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
                    {
                        try
                        {
                            writer.Write(Utility.BuildQueryString(parameters));
                        }
                        finally
                        {
                            writer.Close();
                        }
                    }
                    break;
                }
                string boundary = Utility.GetBoundary();
                request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
                request.AllowWriteStreamBuffering = true;
                using (Stream stream = request.GetRequestStream())
                {
                    try
                    {
                        byte[] buffer = Utility.BuildPostData(boundary, parameters);
                        stream.Write(buffer, 0, buffer.Length);
                    }
                    finally
                    {
                        stream.Close();
                    }
                }
                break;
            }
        }
        try
        {
            using (WebResponse response = request.GetResponse())
            {
                using (reader = new StreamReader(response.GetResponseStream()))
                {
                    try
                    {
                        str2 = reader.ReadToEnd();
                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        reader.Close();
                    }
                }
                response.Close();
            }
        }
        catch (WebException exception2)
        {
            //if (exception2.Response != null)
            //{
            //    using (reader = new StreamReader(exception2.Response.GetResponseStream()))
            //    {
            //        string message = reader.ReadToEnd();
            //        Debug.WriteLine(message);
            //        dynamic obj2 = DynamicJson.Parse(message);
            //        reader.Close();
            //        if (<Request>o__SiteContainer0.<>p__Site1 == null)
            //        {
            //            <Request>o__SiteContainer0.<>p__Site1 = CallSite<Func<CallSite, Type, object, object, object, WeiboException>>.Create(Binder.InvokeConstructor(CSharpBinderFlags.None, typeof(OAuth), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
            //        }
            //        throw <Request>o__SiteContainer0.<>p__Site1.Target(<Request>o__SiteContainer0.<>p__Site1, typeof(WeiboException), string.Format("{0}", obj2.error_code), obj2.error, obj2.request);
            //    }
            //}
            //throw new WeiboException(exception2.Message);
        }
        catch (Exception exception3)
        {
            throw exception3;
        }
        return str2;
    }

        public bool VerifierAccessToken(string accessToken)
        {
            return false;
        }

        // Properties
        public string AccessToken { get; internal set; }

        public string ClientID { get; internal set; }

        public string ClientSecret { get; internal set; }

        public string RefreshToken { get; internal set; }
    }


}

